﻿using ASmile.Com;
using ASmile.Com.MenuRole;
using ASmile.DBModel;
using ASmile.Win.Controls;
using ASmile.Win.Extend;
using System;
using System.Windows.Forms;

namespace ASmile.Win.Forms
{
    public partial class FrmRoleMenu : FrmBase
    {
        public FrmRoleMenu()
        {
            InitializeComponent();
        }

        IMenuRoleBLL BLLObj { get; } = ObjectFactory.GetObject<IMenuRoleBLL>("MenuRoleBLL");

        private void FrmRoleMenu_Load(object sender, EventArgs e)
        {
            InitRole();
            InitTree();
            InitRights();
            dgvRoleMenu.SetInputEdit<Sys_RoleMenu>(Sys_RoleMenu.CNOrderNo, txtRoleMenuOrder, SetCellEdit);
            dgvRoleMenu.SetInputEdit<Sys_RoleMenu>(Sys_RoleMenu.CNToolBarOrderNo, txtRoleToolMenuOrder, SetCellEdit);
            dgvRoleMenu.SetDropMove<Sys_RoleMenu>(DropRoleMenu);
            SetCopyInsertSql<Sys_RoleMenu>(dgvRoleMenu);
        }

        private void InitRights()
        {
            if (IsManager)
            {
                ToolStripEx.LoopItem(SetRights, tsRole, tsTree, tsRoleMenu);

                void SetRights(ToolStripItem tsItem)
                {
                    if (!tsItem.Enabled)
                    {
                        tsItem.Enabled = tsItem.Visible = true;
                    }
                }
            }
        }

        bool SetCellEdit(Sys_RoleMenu m, EditText txt)
        {
            if (txt == txtRoleMenuOrder)
            {
                if (m.OrderNo == txtRoleMenuOrder.Value)
                {
                    return false;
                }
                var ret = BLLObj.SetRoleMenuOrder(m.Id, (int)txtRoleMenuOrder.Value);
                ShowMessage(ret.msg);
            }
            else if (txt == txtRoleToolMenuOrder)
            {
                if (m.ToolBarOrderNo == txtRoleToolMenuOrder.Value)
                {
                    return false;
                }
                var ret = BLLObj.SetRoleToolMenuOrder(m.Id, (int)txtRoleToolMenuOrder.Value);
                ShowMessage(ret.msg);
            }
            return true;
        }

        ApiResult SwapOrderNo(Sys_RoleMenu srcModel, Sys_RoleMenu tarModel)
        {
            var ret =
            BLLObj.SwapOrderNo(new ArgSwapOrderNo
            {
                SrcId = srcModel.Id,
                SrcOrderNo = srcModel.OrderNo,
                TarId = tarModel.Id,
                TarOrderNo = tarModel.OrderNo
            });
            if (ret)
            {
                var tarOrder = tarModel.OrderNo;
                tarModel.OrderNo = srcModel.OrderNo;
                srcModel.OrderNo = tarOrder;
            }
            return ret;
        }


        #region 角色维护

        Sys_Role _CurrRole;

        void InitRole()
        {
            dgvRole.SelectionChangedAndCellClick += DgvRole_SelectionChangedAndCellClick;

            RefrashRoleData();
        }

        private void DgvRole_SelectionChangedAndCellClick(object sender, DataGridViewCellEventArgs e)
        {
            _CurrRole = dgvRole.GetSelectedClassData<Sys_Role>();
            RefrashTreeData();
        }

        void RefrashRoleData()
        {
            dgvRole.DataSource = BLLObj.RoleGetData().data;
            _CurrMenuTree = null;
            RefrashTreeData();
        }

        private void tsBtnRoleRefrash_Click(object sender, EventArgs e)
        {
            RefrashRoleData();
        }

        private void tsBtnRoleAdd_Click(object sender, EventArgs e)
        {
            FrmRoleEdit frm = new FrmRoleEdit();
            var saveModel = new Sys_Role();
            var r =
            frm.ShowDialog(new EditFormArgs
            {
                SaveHandle = (m) => BLLObj.RoleAdd(m as Sys_Role),
                SaveModel = saveModel
            });
            if (r)
            {
                saveModel.Id = r.data;
                dgvRole.AddDataSource(saveModel);
                ShowMessage(r.msg);
            }
        }

        private void tsBtnRoleEdit_Click(object sender, EventArgs e)
        {
            var selRole = dgvRole.GetSelectedClassData<Sys_Role>();
            if (selRole == null)
            {
                ShowMessage("未选中编辑记录");
                return;
            }

            FrmRoleEdit frm = new FrmRoleEdit();
            var r =
            frm.ShowDialog(new EditFormArgs
            {
                SaveHandle = (m) => BLLObj.RoleEdit(m as Sys_Role),
                SaveModel = selRole,
                SetModel = selRole,
                IsEditShow = true
            });
            if (r)
            {
                ShowMessage(r.msg);
                dgvRole.Refresh();
            }

        }

        private void tsBtnRoleDel_Click(object sender, EventArgs e)
        {
            var selRole = dgvRole.GetSelectedClassData<Sys_Role>();
            if (selRole == null)
            {
                ShowMessage("未选中任何记录");
                return;
            }
            if (!ShowQuestion("确实要删除当前选中角色吗?", "删除确认"))
            {
                return;
            }

            var ret = BLLObj.RoleDel(selRole);
            if (ret)
            {
                dgvRole.DelDataSource(selRole);
            }
            ShowMessage(ret.msg);
        }


        #endregion

        #region 角色菜单节点

        Sys_RoleMenu _CurrMenuTree;

        void SetTreeNode(TreeNode node, Sys_RoleMenu m)
        {
            node.Name = m.Id;
            node.Tag = m;
            node.Text = $"{m.OrderNo:D2}.{m.MenuCaption}";
            if (!m.IsMenu)
            {
                node.ImageIndex = 0;
                node.SelectedImageIndex = 0;
                node.ContextMenuStrip = cmNodeOperate;
            }
            else
            {
                node.ImageIndex = 1;
                node.SelectedImageIndex = 1;
            }
        }

        readonly string _ToolBarNodeName = "ToolBarNodeName";

        void InitTree()
        {
            tvRoleMenu.AllowDropNode = true;
            tvRoleMenu.DropNodeBefore += TvRoleMenu_DropNodeBefore;
            tvRoleMenu.AfterSelect += TvRoleMenu_AfterSelect;
        }

        void RefrashTreeData()
        {
            RefrashTreeData(tvRoleMenu);
        }

        void RefrashTreeData(TreeViewEx tv)
        {
            if (_CurrRole != null)
            {
                var treeList = BLLObj.TreeGetData(_CurrRole.Id).data;
                tv.InitTreeViewData(treeList, SetTreeNode);
                var toolNode = tv.Nodes.Add(_ToolBarNodeName, "工具栏菜单");
                toolNode.SelectedImageIndex = 2;
                toolNode.ImageIndex = 2;
            }
            else
            {
                tv.Nodes.Clear();
            }
            dgvRoleMenu.DataSource = null;
        }

        private void tsBtnTreeRefrash_Click(object sender, EventArgs e)
        {
            RefrashTreeData();
        }

        private void TvRoleMenu_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Name == _ToolBarNodeName)
            {
                _CurrMenuTree = null;
                RefrashRoleMenuData(true);
                return;
            }

            var selModel = e.Node.Tag as Sys_RoleMenu;
            if (selModel.IsMenu) return;
            _CurrMenuTree = selModel;
            RefrashRoleMenuData();
        }

        private void tsBtnTreeAddTop_Click(object sender, EventArgs e)
        {
            if (_CurrRole == null)
            {
                ShowMessage("请选中角色");
                return;
            }
            var model = new Sys_RoleMenu
            {
                OrderNo = tvRoleMenu.Nodes.Count + 1,
                RoleId = _CurrRole.Id,
                RoleName = _CurrRole.RoleName,
            };
            FrmMenuTreeEdit frm = new FrmMenuTreeEdit();
            frm.Text += " - 新增";
            var ret = frm.ShowDialog(new EditFormArgs
            {
                SetModel = model,
                SaveHandle = (m) => BLLObj.TreeAdd(m as Sys_RoleMenu)
            });
            if (ret)
            {
                model.Id = ret.data;
                TreeNode node = new TreeNode();

                SetTreeNode(node, model);
                tvRoleMenu.Nodes.Add(node);
                tvRoleMenu.SelectedNode = node;
                ShowMessage(ret.msg);
            }
        }

        private void tsMenuTreeAddSub_Click(object sender, EventArgs e)
        {
            TreeNode selNode = tvRoleMenu.SelectedNode;
            Sys_RoleMenu selModel = selNode.Tag as Sys_RoleMenu;
            var model = new Sys_RoleMenu
            {
                PId = selNode.Name,
                PCaption = selNode.FullPath,
                OrderNo = selNode.Nodes.Count + 1,
                RoleId = selModel.RoleId,
                RoleName = selModel.RoleName
            };
            FrmMenuTreeEdit frm = new FrmMenuTreeEdit();
            frm.Text += " - 新增";
            var ret = frm.ShowDialog(new EditFormArgs
            {
                SetModel = model,
                SaveHandle = (m) => BLLObj.TreeAdd(m as Sys_RoleMenu)
            });

            if (ret)
            {
                model.Id = ret.data;
                TreeNode node = new TreeNode();
                SetTreeNode(node, model);
                selNode.Nodes.Add(node);
                tvRoleMenu.SelectedNode = node;
                ShowMessage(ret.msg);
            }
        }

        private void tsMenuTreeEdit_Click(object sender, EventArgs e)
        {
            TreeNode selNode = tvRoleMenu.SelectedNode;
            if (selNode == null) return;
            Sys_RoleMenu model = selNode.Tag as Sys_RoleMenu;
            if (model == null)
            {
                ShowMessage("错误的节点");
                return;
            }
            model.PCaption = selNode.Parent?.FullPath;
            FrmMenuTreeEdit frm = new FrmMenuTreeEdit();
            frm.Text += " - 修改";
            var ret = frm.ShowDialog(new EditFormArgs
            {
                SetModel = model,
                SaveHandle = (m) => BLLObj.TreeEdit(m as Sys_RoleMenu)
            });
            if (ret)
            {
                //SetTreeNode(model, selNode);
                SetTreeNode(selNode, model);
                tvRoleMenu.SelectedNode = selNode;
                ShowMessage(ret.msg);
            }
        }

        private void tsMenuTreeDel_Click(object sender, EventArgs e)
        {
            if (ShowQuestion("确实要移除当前节点吗?", "移除确认"))
            {
                var selNode = tvRoleMenu.SelectedNode;
                var ret = BLLObj.TreeDel(selNode.Tag as Sys_RoleMenu);
                if (ret)
                {
                    selNode.Remove();
                }
                ShowMessage(ret.msg);
            }
        }

        private void tsMenuTreeSetTop_Click(object sender, EventArgs e)
        {
            if (!ShowQuestion("确实要设置为顶级节点吗?", "设置确认"))
            {
                return;
            }
            var selNode = tvRoleMenu.SelectedNode;
            var ret = BLLObj.SetParent(selNode.Name, string.Empty, tvRoleMenu.Nodes.Count + 1);
            if (ret)
            {
                var selModel = selNode.Tag as Sys_RoleMenu;
                selModel.PId = string.Empty;
                selModel.OrderNo = tvRoleMenu.Nodes.Count + 1;
                TreeNode newNode = new TreeNode();
                SetTreeNode(newNode, selModel);
                tvRoleMenu.Nodes.Add(newNode);
                selNode.Remove();
                tvRoleMenu.SelectedNode = newNode;
            }
            ShowMessage(ret.msg);
        }

        private bool TvRoleMenu_DropNodeBefore(TreeNode moveNode, TreeNode targetNode)
        {
            if (targetNode.ImageIndex == 1)
            {
                ShowMessage("不能拖动到菜单项");
                return false;
            }
            if (targetNode.Name == _ToolBarNodeName)
            {
                ShowMessage("不能拖到工具栏");
                return false;
            }
            var selMenu = targetNode.Tag as Sys_RoleMenu;
            if (selMenu.IsMenu)
            {
                ShowMessage("不能拖动到菜单项");
                return false;
            }
            var m = moveNode.Tag as Sys_RoleMenu;
            m.OrderNo = targetNode.Nodes.Count;
            m.PId = targetNode.Name;
            var r = BLLObj.SetParent(m.Id, targetNode.Name, targetNode.Nodes.Count + 1);
            ShowMessage(r.msg);
            return r.success;
        }

        void SwapOrderNo(TreeNode srcNode, TreeNode tarNode)
        {
            if (srcNode.Name == _ToolBarNodeName || tarNode.Name == _ToolBarNodeName)
            {
                ShowMessage("工具栏节点不能操作");
                return;
            }

            var tarModel = tarNode.Tag as Sys_RoleMenu;
            var srcModel = srcNode.Tag as Sys_RoleMenu;

            var ret = SwapOrderNo(srcModel, tarModel);
            if (ret)
            {
                var newSrcNode = srcNode.Clone() as TreeNode;
                var newTarNode = tarNode.Clone() as TreeNode;
                if (tarNode.Level == 0)
                {
                    tvRoleMenu.Nodes.Insert(tarNode.Index, newSrcNode);
                    tvRoleMenu.Nodes.Insert(srcNode.Index, newTarNode);
                }
                else
                {
                    tarNode.Parent.Nodes.Insert(tarNode.Index, newSrcNode);
                    tarNode.Parent.Nodes.Insert(srcNode.Index, newTarNode);
                }
                srcNode.Remove();
                tarNode.Remove();
                tvRoleMenu.SelectedNode = newSrcNode;


            }
            ShowMessage(ret.msg);
        }

        private void tsMenuSetUp_Click(object sender, EventArgs e)
        {
            TreeNode srcNode = tvRoleMenu.SelectedNode;
            TreeNode tarNode = srcNode.PrevNode;
            if (tarNode == null)
            {
                ShowMessage("已经是最上了");
                return;
            }
            SwapOrderNo(srcNode, tarNode);
        }

        private void tsMenuSetDown_Click(object sender, EventArgs e)
        {
            TreeNode srcNode = tvRoleMenu.SelectedNode;
            TreeNode tarNode = srcNode.NextNode;
            if (tarNode == null)
            {
                ShowMessage("已经是最下了");
                return;
            }
            SwapOrderNo(srcNode, tarNode);
        }

        
        void DropRoleMenu(Sys_RoleMenu srcModel, Sys_RoleMenu tarModel)
        {
            var ret = SwapOrderNo(srcModel, tarModel);
            if (ret)
            {
                var tarOrder = tarModel.OrderNo;
                tarModel.OrderNo = srcModel.OrderNo;
                srcModel.OrderNo = tarOrder;

                dgvRoleMenu.Refresh();
            }
            ShowMessage(ret.msg);
        }

        #endregion

        #region 角色菜单

        void RefrashRoleMenuData(bool isToolMenuData = false)
        {
            if (_CurrMenuTree == null && !isToolMenuData)
            {
                dgvRoleMenu.DataSource = null;
            }
            else
            {
                var ret =
                BLLObj.GetRoleMenus(new ArgGetRoleMenus
                { 
                    RoleId = _CurrRole.Id,
                    IsToorBar = isToolMenuData,
                    PId = _CurrMenuTree?.Id,
                    SearchVal = tsTxtMenuSearch.Text
                });
                dgvRoleMenu.DataSource = ret.data;
            }
        }

        void InitMenuTreeData(TreeViewEx tv)
        {
            var menuList = BLLObj.GetMenuTree().data;
            tv.InitTreeViewData(menuList, AddedNode);
            tv.ImageList = this.imageList1;
            void AddedNode(TreeNode node, Sys_Menu menu)
            {
                if (menu.IsMenu)
                {
                    node.ImageIndex = 1;
                    node.SelectedImageIndex = 1;
                }
            }
        }

        private void tsRoleMneuAdd_Click(object sender, EventArgs e)
        {
            var selNode = tvRoleMenu.SelectedNode;
            if (selNode == null)
            {
                ShowMessage("请选择一个菜单分类");
                return;
            }
            Sys_RoleMenu saveModel = new Sys_RoleMenu();
            saveModel.PId = selNode.Name;
            saveModel.PCaption = selNode.FullPath;
            saveModel.RoleId = _CurrRole.Id;
            saveModel.RoleName = _CurrRole.RoleName;
            saveModel.OrderNo = dgvRoleMenu.RowCount + 1;
            saveModel.IsMenu = true;
            var frm = new FrmRoleMenuEdit();
            frm.InitMenuTreeHandle = InitMenuTreeData;
            var arg = new EditFormArgs
            {
                ClearId = true,
                SaveHandle = (menu) => BLLObj.AddRoleMenu(menu as Sys_RoleMenu),
                SaveModel = saveModel,
                SetModel = saveModel
            };
            var ret = frm.ShowDialog(arg);
            if (ret)
            {
                ShowMessage(ret.msg);
                saveModel.Id = ret.data;

                dgvRoleMenu.AddDataSource(saveModel);
            }
        }

        private void tsBtnRoleMenuEdit_Click(object sender, EventArgs e)
        {
            var selMenu = dgvRoleMenu.GetSelectedClassData<Sys_RoleMenu>();
            if (selMenu == null)
            {
                ShowMessage("没有选中记录");
                return;
            }
            var selNode = tvRoleMenu.SelectedNode;
            selMenu.PCaption = selNode.FullPath;
            selMenu.RoleName = _CurrRole.RoleName;
            selMenu.RoleId = _CurrRole.Id;
            var frm = new FrmRoleMenuEdit();
            frm.InitMenuTreeHandle = InitMenuTreeData;
            frm.Text += " 修改";
            var arg = new EditFormArgs
            {
                SaveHandle = (menu) => BLLObj.EditRoleMenu(menu as Sys_RoleMenu),
                SaveModel = selMenu,
                SetModel = selMenu,
                IsEditShow = true
            };
            var ret = frm.ShowDialog(arg);
            if (ret)
            {
                ShowMessage(ret.msg);
                dgvRoleMenu.Refresh();
            }
        }

        private void tsBtnRoleMenuDel_Click(object sender, EventArgs e)
        {
            var selMenu = dgvRoleMenu.GetSelectedClassData<Sys_RoleMenu>();
            if (selMenu == null)
            {
                ShowMessage("没有选中记录");
                return;
            }
            if (!ShowQuestion("确实要删除当前选中记录吗？", "删除确认"))
            {
                return;
            }
            var ret = BLLObj.DelRoleMenu(selMenu);
            if (ret)
            {
                dgvRoleMenu.DelDataSource(selMenu);
                tvRoleMenu.SetSelectedNode(selMenu.PId);
            }
            ShowMessage(ret.msg);
        }

        private void tsTxtMenuSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                tsBtnSearch_Click(sender, e);
            }
        }

        private void tsBtnSearch_Click(object sender, EventArgs e)
        {
            RefrashRoleMenuData();
        }

        private void tsBtnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        #endregion
    }
}